<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>引用赋值-深拷贝浅拷贝使用</title>
  <!-- 
  在 JavaScript 中，赋值操作可以分为两种：引用赋值和值赋值。在处理对象和数组时，深拷贝和浅拷贝的概念非常重要。
  一、值赋值与引用赋值
  1. 值赋值：
    - 对于基本数据类型（如  `number` 、 `string` 、 `boolean` 、 `null` 、 `undefined`  和  `symbol` ），赋值时会将值直接复制到新的变量中。
    - 修改新变量的值不会影响原变量。
  let a = 10;
    let b = a; // 值赋值
    b = 20;
    console.log(a); // 输出: 10
    console.log(b); // 输出: 20
  2. 引用赋值：
    - 对于对象和数组，赋值时会将对象的引用（地址）复制到新的变量中。
    - 修改新变量的属性或元素会影响原对象或数组，因为它们指向同一个内存地址。
  let obj1 = { name: '小明' };
    let obj2 = obj1; // 引用赋值
    obj2.name = '小红';
    console.log(obj1.name); // 输出: 小红
  二、浅拷贝

  浅拷贝是指创建一个新的对象或数组，但只复制第一层的属性或元素。如果原对象的属性是引用类型，则新对象的属性仍然指向原对象的引用。

   1. 使用  `Object.assign()`
  let obj1 = { a: 1, b: { c: 2 } };
  let obj2 = Object.assign({}, obj1); // 浅拷贝
  obj2.b.c = 3;
  console.log(obj1.b.c); // 输出: 3，原对象也被影响
   2. 使用扩展运算符
  let arr1 = [1, 2, { a: 3 }];
  let arr2 = [...arr1]; // 浅拷贝
  arr2[2].a = 4;
  console.log(arr1[2].a); // 输出: 4，原数组也被影响
  三、深拷贝

  深拷贝是指创建一个新的对象或数组，并递归地复制所有层级的属性或元素。这样，原对象和新对象之间就没有任何引用关系。

   1. 使用  `JSON.stringify()`  和  `JSON.parse()` 

  这种方法适用于简单对象和数组，但不适用于包含函数、 `undefined` 、 `Symbol` 、 `Date` 、 `RegExp`  等特殊对象。
  let obj1 = { a: 1, b: { c: 2 } };
  let obj2 = JSON.parse(JSON.stringify(obj1)); // 深拷贝
  obj2.b.c = 3;
  console.log(obj1.b.c); // 输出: 2，原对象未被影响
   2. 使用递归函数

  可以手动实现深拷贝，适用于更复杂的对象。
  function deepClone(obj) {
      if (obj === null || typeof obj !== 'object') return obj;
      if (Array.isArray(obj)) {
          return obj.map(item => deepClone(item));
      }
      const newObj = {};
      for (let key in obj) {
          newObj[key] = deepClone(obj[key]);
      }
      return newObj;
  }

  let obj1 = { a: 1, b: { c: 2 } };
  let obj2 = deepClone(obj1); // 深拷贝
  obj2.b.c = 3;
  console.log(obj1.b.c); // 输出: 2，原对象未被影响
  四、总结

  - 值赋值：基本数据类型直接复制值，修改不会影响原变量。
  - 引用赋值：对象和数组复制引用，修改会影响原对象。
  - 浅拷贝：只复制第一层，引用类型的属性仍然指向原对象。
  - 深拷贝：递归复制所有层级，原对象和新对象之间没有引用关系。
  - 常用的浅拷贝方法包括  `Object.assign()`  和扩展运算符；深拷贝可以使用  `JSON.stringify()`  和  `JSON.parse()` ，以及手动实现的递归函数。

  通过理解深拷贝和浅拷贝的概念，可以更好地处理对象和数组，避免不必要的引用问题。
  -->
</head>
<body>

  <script>

    const obj = {
      name: '张三',
      age: 18,
      gender: '男',
      car: {
        name: '奔驰',
        price: 200000,
        color: 'red'
      }
    }

    // 1. 引用赋值(浅拷贝)
    const info1 = obj
    info1.name = '李四'
    console.log(obj.name, info1.name)

    // 2. 浅拷贝
    const info2 = { ...obj }
    info2.name = '王五'
    console.log(obj.name, info2.name)

    // 3. 深拷贝
    // 方式一: 第三方库
    // 方式二: 自己实现
    // function deepCopy(obj) {}
    // 方式三: 利用先有的js机制, 实现深拷贝JSON.stringify()和JSON.parse()
    const info3 = JSON.parse(JSON.stringify(obj))
    info3.name = '赵六'
    console.log(obj.name, info3.name) 
    
  </script>
  
</body>
</html>